home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / prio / _p_aux_heap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  10.1 KB  |  450 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _p_aux_heap.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/impl/p_aux_heap.h>
  16.  
  17. static p_aux_heap const *class_ptr;
  18.  
  19. #define comparison_link(with_el,new_el)\
  20.   if ((cmp(with_el->key,new_el->key)<0)||(with_el==minptr))\
  21.    {  with_el->r_child=new_el->r_child;\
  22.       if (with_el->r_child!=nil)\
  23.               with_el->r_child->parent=with_el;\
  24.       new_el->r_child=with_el->l_child;\
  25.       if (new_el->r_child!=nil)\
  26.               new_el->r_child->parent=new_el;\
  27.       new_el->parent=with_el;  \
  28.       with_el->l_child=new_el; }\
  29.   else\
  30.     { with_el->r_child=new_el->l_child;\
  31.       if (with_el->r_child!=nil)\
  32.               with_el->r_child->parent=with_el;\
  33.       new_el->parent=with_el->parent;\
  34.       if (new_el->parent!=nil)\
  35.               new_el->parent->r_child=new_el; \
  36.       new_el->l_child=with_el;\
  37.       with_el->parent=new_el;\
  38.       with_el = new_el; }
  39.  
  40. #define int_comparison_link(with_el,new_el)\
  41.   if ((with_el->key < new_el->key)||(with_el==minptr))\
  42.     { with_el->r_child=new_el->r_child;\
  43.       if (with_el->r_child!=nil)\
  44.               with_el->r_child->parent=with_el;\
  45.       new_el->r_child=with_el->l_child;\
  46.       if (new_el->r_child!=nil)\
  47.               new_el->r_child->parent=new_el;\
  48.       new_el->parent=with_el;  \
  49.       with_el->l_child=new_el; }\
  50.   else\
  51.     { with_el->r_child=new_el->l_child;\
  52.       if (with_el->r_child!=nil)\
  53.               with_el->r_child->parent=with_el;\
  54.       new_el->parent=with_el->parent;\
  55.       if (new_el->parent!=nil)\
  56.               new_el->parent->r_child=new_el; \
  57.       new_el->l_child=with_el;\
  58.       with_el->parent=new_el;\
  59.       with_el = new_el; }
  60.  
  61.  
  62. //&&&&&&&&&&&&&&&&  p_heap &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  63.  
  64. //======= construct ===================================================
  65.  
  66. p_aux_heap::p_aux_heap()
  67. {
  68.     item_count=0;
  69. }
  70.     
  71. //====== construct (p_aux_heap&) ===========================================
  72.  
  73. p_aux_heap::p_aux_heap(const p_aux_heap& with)
  74. {
  75.     
  76.     item_count =0;
  77.     if((this!=&with)&&(with.item_count>0)){
  78.     class_ptr=&with;
  79.     head=new ph_item(with.head->key,with.head->inf);
  80.     class_ptr->copy_key(head->key);
  81.     class_ptr->copy_inf(head->inf);
  82.     item_count++;
  83.     if (with.head->l_child!=nil)
  84.           do_copy(head,with.head->l_child,true);
  85.     if (with.head->r_child!=nil)
  86.         do_copy(head,with.head->r_child,false);
  87.     class_ptr=this;
  88.     }
  89. }
  90.  
  91. //====== operator = =====================================================
  92.  
  93. p_aux_heap& p_aux_heap::operator=(const p_aux_heap& with)
  94. {
  95.       if(this!=&with){
  96.      if((with.item_count>0)&&(item_count>0))
  97.         clear();
  98.     class_ptr=&with;
  99.     head=new ph_item(with.head->key,with.head->inf);
  100.     class_ptr->copy_key(head->key);
  101.     class_ptr->copy_inf(head->inf);
  102.     item_count++;
  103.     if (with.head->l_child!=nil)
  104.           do_copy(head,with.head->l_child,true);
  105.     if (with.head->r_child!=nil)
  106.         do_copy(head,with.head->r_child,false);
  107.     class_ptr=this;
  108.         
  109.     }
  110.     return(*this);
  111. }
  112.  
  113.  
  114.  
  115. //====== do_copy ======================================================
  116.  
  117. void p_aux_heap::do_copy(ph_item* father,ph_item* from,bool direction)
  118. {
  119. // direction : false=right true=left
  120.  
  121.     
  122.     ph_item* hilf=new ph_item(from->key,from->inf);
  123.     class_ptr->copy_key(hilf->key);
  124.     class_ptr->copy_inf(hilf->inf);
  125.     if (class_ptr->minptr==from)
  126.         minptr=hilf;
  127.     item_count++;
  128.  
  129.     hilf->parent=father;
  130.     if (direction)
  131.         father->l_child=hilf;
  132.     else
  133.         father->r_child=hilf;
  134.  
  135.     if (from->l_child!=nil)
  136.         do_copy(hilf,from->l_child,true);
  137.         
  138.     if (from->r_child!=nil)
  139.         do_copy(hilf,from->r_child,false);
  140. }
  141.         
  142.  
  143.  
  144.  
  145.  
  146. //======= insert =======================================================
  147.  
  148. ph_item* p_aux_heap::insert(GenPtr key,GenPtr inf)
  149. {    
  150.     ph_item* help;
  151.  
  152.     
  153.     help = new ph_item(key,inf);
  154.     copy_key(help->key);
  155.     copy_inf(help->inf);
  156.  
  157.     if (item_count==0)    // very first element
  158.     {
  159.             
  160.         item_count++;
  161.         head=help;
  162.         minptr=help;
  163.         return head;
  164.     }
  165.         
  166.     else{                // just another element
  167.         
  168.         item_count++;
  169.         if(cmp(minptr->key,help->key)>=0)
  170.             minptr=help;
  171.  
  172.         if (head->r_child==nil)
  173.         {
  174.             help->parent=head;
  175.             head->r_child=help;
  176.         }
  177.         else
  178.         {
  179.             help->r_child=head->r_child;
  180.             head->r_child->parent=help;    
  181.             head->r_child=help;
  182.             help->parent=head;
  183.         }    // insert at the beginning of the r_child of head
  184.  
  185.         return help;
  186.     }
  187.  
  188.     
  189. }
  190.  
  191.  
  192. // ====== decrease_key ==================================================
  193.  
  194. void p_aux_heap::decrease_key(ph_item* which,GenPtr key)
  195. {
  196.     
  197.  
  198.   if (cmp(key,which->key)<=0)   // smaler or equal compared to the old key
  199.   {
  200.     clear_key(which->key);    
  201.     which->key=key;
  202.     copy_key(which->key);
  203.     if (cmp(which->key,minptr->key)<=0)
  204.         minptr=which;
  205.     if (which!=head)    // which is not already minimum
  206.     {  
  207.         if (which->parent->l_child==which){
  208.             if (which->r_child!=nil){
  209.                 which->parent->l_child=which->r_child;
  210.                 which->r_child->parent=which->parent;
  211.                 which->r_child=nil;
  212.             }
  213.             else
  214.                 which->parent->l_child=nil;
  215.         }
  216.         else {
  217.             if (which->r_child!=nil){
  218.                 which->parent->r_child=which->r_child;
  219.                 which->r_child->parent=which->parent;
  220.                 which->r_child=nil;
  221.             }
  222.             else
  223.                 which->parent->r_child=nil;
  224.         }
  225.  
  226.                 
  227.         if (head->r_child==nil){
  228.             head->r_child=which;
  229.             which->parent=head;
  230.         }
  231.         else
  232.         {
  233.             which->r_child=head->r_child;
  234.             head->r_child->parent=which;
  235.             head->r_child=which;
  236.             which->parent=head;
  237.                 
  238.         }        
  239.     }
  240.     
  241.   }
  242. }
  243.  
  244.                 
  245.         
  246. //========= delete_min_aux_multipass ()  (auxiliary multipass algorithm) =============
  247.  
  248. void p_aux_heap::delete_min_multipass()
  249. {  
  250.    ph_item *help;    
  251.  
  252.    if (head->r_child!=nil){
  253.     if (head->r_child->r_child!=nil){
  254.         help=head->r_child;
  255.         help->parent=nil;
  256.         help=multipass(help);
  257.     }
  258.           comparison_link(head,help);    // vorher head = ...
  259.     if (head->parent==help)
  260.         head=help;
  261.    }
  262.     
  263.  
  264.    if (item_count==1)    // only one element in structure
  265.    {
  266.     clear_key(head->key);
  267.     clear_inf(head->inf);
  268.     delete head;
  269.     item_count=0;
  270.    }
  271.    else
  272.    {
  273.          head=head->l_child;
  274.     clear_key(head->parent->key);
  275.     clear_inf(head->parent->inf);
  276.     delete head->parent;    // delete min
  277.     head->parent=nil;
  278.     item_count--;
  279.  
  280.      
  281.       if (head->r_child!=nil)    // there are two ore more consecutive elements
  282.           head=multipass(head);
  283.  
  284.   }// end else
  285.  
  286. minptr=head;
  287.  
  288.  
  289. }
  290.  
  291. //======== delete_min_aux_twopass, (auxiliary twopass algorithm) =============
  292.  
  293. void p_aux_heap::delete_min_twopass()
  294. {
  295.   ph_item *help;    
  296.  
  297.    if (head->r_child!=nil){
  298.     help=head->r_child;
  299.     if (head->r_child->r_child!=nil){
  300.         help->parent=nil;
  301.         help=multipass(help);
  302.     }
  303.        comparison_link(head,help);
  304.    }
  305.  
  306.      
  307.   
  308.    if (item_count==1)    // only one element in structure
  309.    {
  310.     clear_key(head->key);
  311.     clear_inf(head->inf);
  312.     delete head;
  313.     item_count=0;
  314.    }
  315.    else
  316.    {
  317.          head=head->l_child;
  318.     clear_key(head->parent->key);
  319.     clear_inf(head->parent->inf);
  320.     delete head->parent;    // delete min
  321.     head->parent=nil;
  322.     item_count--;
  323.     
  324.       if (head->r_child!=nil)    // there are two ore more consecutive elements
  325.           head=twopass(head);
  326.  
  327.    } // end else
  328.  
  329. minptr=head;
  330.  
  331. }
  332.         
  333. // ============== twopass ================================================              
  334.         
  335. ph_item*  p_aux_heap::twopass(ph_item* head)
  336. {
  337.  //pass 1 : left to right comparison link (successive pairs of root nodes)
  338.  
  339.   register ph_item* help1,*help2;
  340.  
  341.   help1=head;
  342.   help2=head->r_child;
  343.   
  344.   if (int_type())
  345.         while (help2!=nil)               // there are 2 ore more elements left
  346.         { head=help1->r_child->r_child;   // use of head as a helper
  347.           int_comparison_link(help1,help2);
  348.                 
  349.           if (head!=nil)       // first case comp _link
  350.              if (head->r_child!=nil)
  351.                { // second case
  352.                  // now we have to more nodes to test
  353.                  help2=head->r_child;
  354.                  help1=head;
  355.                 }
  356.              else
  357.                help2=nil;
  358.            else
  359.              { head=help1;     // last element in list
  360.                help2=nil;
  361.               }
  362.           }
  363.    else
  364.         while (help2!=nil)
  365.         { head=help1->r_child->r_child;
  366.           comparison_link(help1,help2);
  367.                 
  368.           if (head!=nil)
  369.              if (head->r_child!=nil)
  370.                { help2=head->r_child;
  371.                  help1=head;
  372.                 }
  373.              else
  374.                help2=nil;
  375.            else
  376.              { head=help1;
  377.                help2=nil;
  378.               }
  379.          }
  380.  
  381.   //pass 2 : right to left comparison link (allways the two rightmost nodes)
  382.  
  383.         help1=head->parent;
  384.         help2=head;
  385.  
  386.    if (int_type())
  387.         while (help1!=nil)
  388.         { int_comparison_link(help1,help2);
  389.       head=help1;
  390.           help2=help1;
  391.           help1=help1->parent;
  392.          }
  393.     else
  394.         while (help1!=nil)
  395.         { comparison_link(help1,help2);
  396.       head=help1;
  397.           help2=help1;
  398.           help1=help1->parent; 
  399.      }
  400.         
  401.  // head points now again to the very first element
  402.  
  403.  return(head);
  404.  
  405. }
  406.  
  407. // ================ multipass ==========================================
  408.  
  409. ph_item* p_aux_heap::multipass(ph_item* head)
  410. {
  411.           // now pass 1 (multi times) : left to right comparison link (successive pairs of root nodes)
  412.        ph_item* save=head;      
  413.        ph_item* help1,*help2;
  414.  
  415.        while(head->r_child!=nil)
  416.        { save=head;
  417.          help1=head;
  418.          help2=head->r_child;
  419.         
  420.          while (help2!=nil)      // there are 2 ore more elements left
  421.          { save=help1->r_child->r_child; // use of save as a helper
  422.            comparison_link(help1,help2);
  423.        if (help1->parent==help2)
  424.         help1=help2;
  425.                 
  426.            if (save!=nil)       // first case comp _link
  427.              if (save->r_child!=nil)
  428.                 { // second case
  429.                   // now we have to more nodes to test
  430.                   help2=save->r_child;
  431.                   help1=save;
  432.                  }
  433.               else
  434.                  help2=nil;
  435.            else
  436.               { save=help1;     // last element in list
  437.                 help2=nil;
  438.                }
  439.          } // end while (help2!=nil)
  440.  
  441.  
  442.            if (head->parent!=nil)      // may be first element is child (comp link)
  443.              head=head->parent;
  444.  
  445.     } // end while (repeat pass 1)
  446.  
  447.   return(head);
  448. }
  449.